--列出当前用户可访问的所有触发器
SELECT * FROM USER_TRIGGERS;
--列出所有触发器
SELECT * FROM all_triggers;
--列出数据库管理员可见的所有触发器
SELECT * FROM dba_triggers;

/*创建更新TABLE_1的主键字段的触发器
触发器与某个表关联后，如果删除相应表，那么触发器也会被删除*/
--BEFORE|after|instead of表示在事件发生之前|发生之后|替换值时触发
--支持的触发事件（选择DML、DDL、数据库事件三者其一）
--DML：insert|update|delete
--DDL：create|alter|drop，可同时支持多个DDL条件
--数据库事件：servererror|logon|logoff|startup|shutdown
CREATE TRIGGER UPDATE_TABLE_1_PK_TRI BEFORE
--FOR EACH ROW（可选）表示行级触发，没有此项则表示语句级触发
--行级触发：当触发DML事件时，一条DML语句更新多少行，就触发多少次
--语句级触发：当触发DML事件时，不管一条DML语句更新多少行，都只触发一次
INSERT ON TABLE_1 FOR EACH ROW WHEN(NEW.COLUMN_1 IS NULL)
BEGIN
  /*NEW：用于添加型触发器或更新型触发器，表示刚刚添加或更新后的那一条记录
  以“.NEW.列名”的格式获取此条记录中的指定列的值
  NEW只能用于行级触发器*/
  SELECT TABLE_1_PK_SEQ.NEXTVAL INTO:NEW.COLUMN_1 FROM DUAL;
END;

--创建更新TABLE_2的主键字段的触发器
CREATE TRIGGER UPDATE_TABLE_2_PK_TRI BEFORE
INSERT ON TABLE_2 FOR EACH ROW WHEN(NEW.COLUMN_4 IS NULL)
BEGIN
SELECT TABLE_2_PK_SEQ.NEXTVAL INTO:NEW.COLUMN_4 FROM DUAL;
END;

--列出当前用户可访问的所有触发器
SELECT * FROM USER_TRIGGERS;
--列出所有触发器
SELECT * FROM ALL_TRIGGERS;
--列出数据库管理员可见的所有触发器
SELECT * FROM DBA_TRIGGERS;

/*创建更新TABLE_1的主键字段的触发器
触发器与某个表关联后，如果删除相应表，那么触发器也会被删除*/
--BEFORE|AFTER|INSTEAD OF表示在事件发生之前|发生之后|替换值时触发
--支持的触发事件（选择DML、DDL、数据库事件三者其一）
--DML：INSERT|UPDATE|DELETE
--DDL：CREATE|ALTER|DROP，可同时支持多个DDL条件
--数据库事件：SERVERERROR|LOGON|LOGOFF|STARTUP|SHUTDOWN
CREATE TRIGGER UPDATE_TABLE_1_PK_TRI BEFORE
--FOR EACH ROW（可选）表示行级触发，没有此项则表示语句级触发
--行级触发：当触发DML事件时，一条DML语句更新多少行，就触发多少次
--语句级触发：当触发DML事件时，不管一条DML语句更新多少行，都只触发一次
INSERT ON TABLE_1 FOR EACH ROW WHEN(NEW.COLUMN_1 IS NULL)
BEGIN
  /*NEW：用于添加型触发器或更新型触发器，表示刚刚添加或更新后的那一条记录
  以“.NEW.列名”的格式获取此条记录中的指定列的值
  NEW只能用于行级触发器*/
  SELECT TABLE_1_PK_SEQ.NEXTVAL INTO:NEW.COLUMN_1 FROM DUAL;
END;

--创建更新TABLE_2的主键字段的触发器
CREATE TRIGGER UPDATE_TABLE_2_PK_TRI BEFORE
INSERT ON TABLE_2 FOR EACH ROW WHEN(NEW.COLUMN_4 IS NULL)
BEGIN
SELECT TABLE_2_PK_SEQ.NEXTVAL INTO:NEW.COLUMN_4 FROM DUAL;
END;

CREATE TRIGGER TRIGGER_1 AFTER INSERT ON CUSTOMERS
DECLARE
  I INTEGER;
BEGIN
  SELECT COUNT(*) INTO I FROM CUSTOMERS;
  DBMS_OUTPUT.PUT_LINE('顾客总数'||I);
END;

--创建基于CUSTOMERS的DELETE事件的触发器
CREATE TRIGGER TRIGGER_2 AFTER DELETE ON CUSTOMERS FOR EACH ROW
DECLARE
BEGIN
  INSERT INTO CUSTOMERS_3
  /*OLD：用于添加型触发器或更新型触发器，表示刚刚删除或更新后的那一条记录
  以“.OLD.列名”的格式获取此条记录中的指定列的值
  OLD只能用于行级触发器*/
  VALUES(:OLD.CUSTOMER_ID,:OLD.CUSTOMER_NAME,:OLD.BIRTHDATE,:OLD.TELEPHONE,:OLD.SEX,:OLD.NOTES);
END;

--创建或替换基于TABLE_2的DELETE事件的触发器
CREATE OR REPLACE TRIGGER TRIGGER_3 AFTER DELETE ON TABLE_2 FOR EACH ROW
DECLARE
BEGIN
  DELETE TABLE_1 WHERE COLUMN_3=:OLD.COLUMN_7;
END;

--创建或替换基于TABLE_1的DELETE事件的触发器
CREATE OR REPLACE TRIGGER TRIGGER_4 BEFORE DELETE ON TABLE_1 FOR EACH ROW
DECLARE
  A INTEGER;
BEGIN
  SELECT COUNT(*) INTO A FROM TABLE_2 WHERE COLUMN_5=:OLD.COLUMN_2;
  IF A>0 THEN
    --此函数用于提示错误信息，第一个参数表示错误号，第二个参数表示错误消息
    --错误号的取值范围：[-20999,-20000]
    RAISE_APPLICATION_ERROR(-20000,:OLD.COLUMN_3||'关联另一表的外键，不能删除');
  END IF;
END;

--创建顾客的日志表
CREATE TABLE CUSTOMERS_LOG(
  USER_NAME NVARCHAR2(30) NOT NULL,
  OPERATE_TIME DATE NOT NULL,
  OPERATE CHAR(6) NOT NULL
);

--创建基于TABLE_1的INSERT，DELETE或UPDATE事件的触发器
CREATE TRIGGER TRIGGER_5 AFTER INSERT OR DELETE OR UPDATE ON CUSTOMERS
BEGIN
  --如果是插入事件，那么
  IF INSERTING THEN
    INSERT INTO CUSTOMERS_LOG VALUES(USER,SYSDATE,'INSERT');
  ELSIF UPDATING THEN
    INSERT INTO CUSTOMERS_LOG VALUES(USER,SYSDATE,'UPDATE');
  ELSIF DELETING THEN
    INSERT INTO CUSTOMERS_LOG VALUES(USER,SYSDATE,'DELETE');
  END IF;
END;

--创建视图
CREATE VIEW TABLE_1_TABLE_2_VIEW
AS
SELECT T1.COLUMN_1,T1.COLUMN_2,T1.COLUMN_3,T2.COLUMN_4,T2.COLUMN_6
FROM TABLE_2 T2,TABLE_1 T1
WHERE T2.COLUMN_7=T1.COLUMN_3;

--为TABLE_1_TABLE_2_VIEW的INSERT事件创建替代型触发器
CREATE TRIGGER TRIGGER_6 INSTEAD OF INSERT ON TABLE_1_TABLE_2_VIEW
FOR EACH ROW
BEGIN
INSERT INTO TABLE_1(COLUMN_2,COLUMN_3) VALUES(:NEW.COLUMN_2,:NEW.COLUMN_3);
INSERT INTO TABLE_2(COLUMN_5,COLUMN_6,COLUMN_7) VALUES(:NEW.COLUMN_2,:NEW.COLUMN_6,:NEW.COLUMN_3);
END;

--为TABLE_1_TABLE_2_VIEW的UPDATE事件创建或替换替代型触发器
CREATE OR REPLACE TRIGGER TRIGGER_7 INSTEAD OF UPDATE ON TABLE_1_TABLE_2_VIEW FOR EACH ROW
BEGIN
  --TABLE_2的COLUMN_5是关联TABLE_1的COLUMN_2的外键，临时将其值设置为NULL
  --TABLE_2的COLUMN_7是关联TABLE_1的COLUMN_3的外键，临时将其值设置为NULL
  UPDATE TABLE_2 SET COLUMN_5=NULL,COLUMN_7=NULL;
  UPDATE TABLE_1 SET COLUMN_2=:NEW.COLUMN_2,COLUMN_3=:NEW.COLUMN_3 WHERE COLUMN_1=:OLD.COLUMN_1;
  UPDATE TABLE_2 SET COLUMN_5=:NEW.COLUMN_2,COLUMN_6=:NEW.COLUMN_6,COLUMN_7=:NEW.COLUMN_3 WHERE COLUMN_4=:NEW.COLUMN_4;
END;

--为TABLE_1_TABLE_2_VIEW的DELETE事件创建替代型触发器
CREATE TRIGGER TRIGGER_8 INSTEAD OF DELETE ON TABLE_1_TABLE_2_VIEW FOR EACH ROW
BEGIN
  DELETE TABLE_2 WHERE COLUMN_4=:OLD.COLUMN_4;
  DELETE TABLE_1 WHERE COLUMN_1=:OLD.COLUMN_1;
END;
